package com.github.hgkmail.hello.cmd;

import com.github.hgkmail.hello.cmd.helper.*;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaParameter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.VelocityContext;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.github.hgkmail.hello.cmd.helper.DocTagUtil.*;
import static java.lang.System.out;

/**
 * 生成建表SQL
 *
 * @author kimhuang
 * @date 2021/2/12
 */
public class GenCreateTableSql extends BaseParseClass {

    public static void main(String[] args) {
        new GenCreateTableSql().run();
    }

    @Override
    public void run() {
        parseClass(new RenderCreateTableSql());
    }

    private class RenderCreateTableSql implements ParseClassListener {
        private TableInfo table = new TableInfo();
        private ColumnInfo primaryColumn = new ColumnInfo();
        private List<ColumnInfo> generalColumns = new ArrayList<>();
        private List<IndexInfo> generalIndexes = new ArrayList<>();

        RenderCreateTableSql() {
        }

        @Override
        public void onStart(JavaClass jClass) {
            table.setName(firstTagValue(jClass, "table", jClass.getName()))
                    .setCharset(firstTagValue(jClass, "charset", "utf8"))
                    .setComment(firstTagValue(jClass, "comment", ""));
        }

        @Override
        public void onField(JavaClass jClass, JavaField jField) {
            ColumnInfo column = new ColumnInfo()
                    .setName(firstTagValue(jField, "column", jField.getName()))
                    .setDbType(firstTagValue(jField, "dbType", "varchar(255)"))
                    .setComment(firstTagValue(jField, "comment", jField.getName()+"字段"))
                    .setDbAttrs(firstTagParams(jField, "dbAttr", new ArrayList<>()))
                    .setDbDefault(firstTagValue(jField, "dbDefault", ""));
            column.setDbAttrsPart("");
            if (CollectionUtils.isNotEmpty(column.getDbAttrs())) {
                column.setDbAttrsPart(Joiner.on(WHITE_SPACE).skipNulls().join(column.getDbAttrs()));
            }

            column.setDbDefaultPart("");
            if (StringUtils.isNotBlank(column.getDbDefault())) {
                List<String> strs = Lists.newArrayList("DEFAULT", column.getDbDefault());
                column.setDbDefaultPart(Joiner.on(WHITE_SPACE).skipNulls().join(strs));
                //默认值放到属性列表
                //有默认值的，字段加上NOT NULL
                List<String> newAttrs;
                if (column.getDbAttrsPart().contains("NULL")) {
                    newAttrs = Lists.newArrayList(column.getDbAttrsPart(), column.getDbDefaultPart());
                } else {
                    newAttrs = Lists.newArrayList(column.getDbAttrsPart(), "NOT NULL", column.getDbDefaultPart());
                }
                column.setDbAttrsPart(Joiner.on(WHITE_SPACE).skipNulls().join(newAttrs));
            }

            if (jField.getTagByName("primary")!=null) {
                primaryColumn = column;
            } else {
                generalColumns.add(column);
            }
        }

        @Override
        public void onMethod(JavaClass jClass, JavaMethod jMethod) {
            JavaClass returnClass = jMethod.getReturns();
            List<JavaParameter> jParams = jMethod.getParameters();
            List<String> columns = jParams.stream().map(p->p.getName()).collect(Collectors.toList());
            List<String> columnsWithQuotes = columns.stream().map(c-> String.format("`%s`", c)).collect(Collectors.toList());
            IndexInfo index = new IndexInfo()
                    .setName(getIndexPrefix(returnClass) + jMethod.getName())
                    .setColumns(columns)
                    .setColumnsPart(Joiner.on(COMMA).skipNulls().join(columnsWithQuotes))
                    .setTypePart(DocTagUtil.getIndexTypePart(returnClass));
            generalIndexes.add(index);
        }

        @Override
        public void onEnd(JavaClass jClass) {
            renderVm("code-maker/generate/create_table_sql.vm", new RenderListener() {
                @Override
                public void beforeRender(VelocityContext vContext) {
                    vContext.put("table", table);
                    vContext.put("primaryColumn", primaryColumn);
                    vContext.put("generalColumns", generalColumns);
                    vContext.put("generalIndexes", generalIndexes);
                }

                @Override
                public void afterRender(VelocityContext vContext, String result) {
                    out.println(result);
                }
            });
        }

    }

}
